#ifndef __HASHTABLE_H__
#define __HASHTABLE_H__

typedef struct _HashTable HashTable;
typedef struct _HashTableEntry HashTableEntry;

typedef int (*_fn_hash_function) (HashTable *tbl, const void *key);
typedef int (*_fn_compare_function) (HashTable *tbl, const void *key1, const void *key2);
typedef void *(*_fn_duplicate_function) (HashTable *tbl, const void *key);
typedef int (*_fn_resolve_collision) (HashTable *tbl, int hash, int i, int *state);

typedef enum _HashTableEntryState { HTE_FREE, HTE_OCCUPIED } HashTableEntryState;

struct _HashTable
{
	int size;
	int num_entries;
	
	HashTableEntry *entries;
	
	_fn_hash_function hash_function;
	_fn_compare_function compare_function;
	_fn_duplicate_function duplicate_function;
	_fn_resolve_collision resolve_collision;
};

struct _HashTableEntry
{
	HashTableEntryState state;
	const void *key;
	void *value;
};

int hashtable_str_hash (HashTable *tbl, const void *key);
int hashtable_str_compare (HashTable *tbl, const void *key1, const void *key2);
void *hashtable_str_duplicate (HashTable *tbl, const void *key);

HashTable *hashtable_new (int size, _fn_hash_function, _fn_compare_function, _fn_duplicate_function);
void hashtable_insert (HashTable *tbl, const void *key, void *value);
void hashtable_remove (HashTable *tbl, const void *key);
void *hashtable_find (HashTable *tbl, const void *key);

#endif

